#ifndef FFMPEGEXTRA_LRUCACHE_HPP
#define FFMPEGEXTRA_LRUCACHE_HPP

#include <mutex>
#include <list>
#include <memory>
#include <map>

namespace Eyer
{
    template <typename T>
    class LRUCacheBean
    {
    public:
        std::string key = "";
        T t;
    };

    template <typename T>
    class LRUCache
    {
    public:
        int PutData(const std::string & key, const T & t)
        {
            std::lock_guard<std::mutex> lg(mut);

            std::shared_ptr<LRUCacheBean<T> > bean = std::make_shared<LRUCacheBean<T> >();
            bean->key = key;
            bean->t = t;
            cache.push_front(bean);

            while(cache.size() >= 10){
                cache.pop_back();
            }
            return 0;
        }

        int GetData(T & t, const std::string & key)
        {
            int ret = -1;
            std::shared_ptr<LRUCacheBean<T> > res;
            for(typename std::list<std::shared_ptr<LRUCacheBean<T> > >::iterator iter = cache.begin(); iter != cache.end();) {
                if((*iter)->key == key) {
                    res = *iter;
                    ret = 0;
                    iter = cache.erase(iter);
                }
                else {
                    iter++;
                }
            }
            if(!ret){
                cache.push_front(res);
                t = res->t;
            }
            return ret;
        }

        int Size()
        {
            std::lock_guard<std::mutex> lg(mut);
            return cache.size();
        }

        int PrintInfo()
        {
            std::lock_guard<std::mutex> lg(mut);
            for(typename std::list<std::shared_ptr<LRUCacheBean<T>>>::iterator iter = cache.begin(); iter != cache.end(); iter++) {
                std::shared_ptr<LRUCacheBean<T>> bean = *iter;
                Log("Bean key: %s\n", bean->key.c_str());
            }
            return 0;
        }
    private:
        std::mutex mut;
        std::list<std::shared_ptr<LRUCacheBean<T>>> cache;
    };

}


#endif //FFMPEGEXTRA_LRUCACHE_HPP
